package com.sxt.caculator;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Caculator {
	private static JFrame frame = null;
	private static JPanel mainPanel = null;
	private static char keyChar; // 按钮按下的值
	private static StringBuilder sb = null; // 结果显示字符
	private static JTextField resultText = null; // 结果显示控件
	private static StringBuilder lastNum = new StringBuilder(); // 前一个操作数
	private static StringBuilder currentNum = new StringBuilder(); // 当前操作数
	private static char operate = 0; // 操作符
	private static int numInputOrder = 0; // 判断操作数的顺序
	private static double result = 0; // 结果
	private static char oTemp = 0; // 操作符暂存

	public static void main(String[] args) {
		new Caculator();
	}

	/**
	 * 构造方法
	 */
	public Caculator() {
		frame = new JFrame("计算器");
		frame.setLocation(500, 200);
		frame.setVisible(true);
		frame.setSize(220, 200);
		frame.setResizable(false);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		// 主面板
		mainPanel = new JPanel();
		BorderLayout mainLayout = new BorderLayout();
		mainPanel.setLayout(mainLayout);

		// 结果框
		resultText = new JTextField(20);
		resultText.setHorizontalAlignment(JTextField.RIGHT);
		resultText.setText("0.0");
		resultText.setEditable(false);

		// 按键面板
		GridLayout numLayout = new GridLayout(4, 4);
		JPanel key = new JPanel();
		key.setLayout(numLayout);

		// 定义所需按键
		JButton b1 = new JButton("1"), b2 = new JButton("2"), b3 = new JButton(
				"3"), b4 = new JButton("4"), b5 = new JButton("5"), b6 = new JButton(
				"6"), b7 = new JButton("7"), b8 = new JButton("8"), b9 = new JButton(
				"9"), b0 = new JButton("0"), bPoint = new JButton("."), bAdd = new JButton(
				"+"), bReduce = new JButton("-"), bRide = new JButton("*"), bDivide = new JButton(
				"/"), bResult = new JButton("=");

		// 添加按键
		key.add(b1);
		key.add(b2);
		key.add(b3);
		key.add(bAdd);
		key.add(b4);
		key.add(b5);
		key.add(b6);
		key.add(bReduce);
		key.add(b7);
		key.add(b8);
		key.add(b9);
		key.add(bRide);
		key.add(bPoint);
		key.add(b0);
		key.add(bResult);
		key.add(bDivide);

		// 添加按钮鼠标监听
		addButtonListioner(b1, '1');
		addButtonListioner(b2, '2');
		addButtonListioner(b3, '3');
		addButtonListioner(b4, '4');
		addButtonListioner(b5, '5');
		addButtonListioner(b6, '6');
		addButtonListioner(b7, '7');
		addButtonListioner(b8, '8');
		addButtonListioner(b9, '9');
		addButtonListioner(b0, '0');
		addButtonListioner(bPoint, '.');
		addButtonListioner(bAdd, '+');
		addButtonListioner(bReduce, '-');
		addButtonListioner(bRide, '*');
		addButtonListioner(bDivide, '/');
		addButtonListioner(bResult, '=');

		frame.addKeyListener(new KeyAdapter() {

			@Override
			public void keyTyped(KeyEvent e) {
				// TODO Auto-generated method stub
				super.keyTyped(e);

				if (e.getKeyChar() >= KeyEvent.VK_0
						&& e.getKeyChar() <= KeyEvent.VK_9) {
					System.out.print(e.getKeyChar());
				} else if (e.getKeyChar() == '+' || e.getKeyChar() == '-'
						|| e.getKeyChar() == '*' || e.getKeyChar() == '/') {
					System.out.print(e.getKeyChar());
				} else if (e.getKeyChar() == '.') {
					System.out.print(e.getKeyChar());
				} else if (e.getKeyChar() == KeyEvent.VK_ENTER) {
					System.out.print("=");
				}
			}

		});

		// 计时器
		final JLabel timer = new JLabel();
		Timer time = new Timer();
		time.schedule(new TimerTask() {
			@Override
			public void run() {
				timer.setText("当前时间："
						+ new SimpleDateFormat("HH:mm:ss").format(new Date()));
			}
		}, 0, 1000);
		timer.setHorizontalAlignment(JLabel.CENTER);

		// 将所有组件加入界面
		mainPanel.add(resultText, BorderLayout.NORTH);
		mainPanel.add(key, BorderLayout.CENTER);
		mainPanel.add(timer, BorderLayout.SOUTH);
		frame.add(mainPanel);
		frame.pack();
	}

	/**
	 * 为按钮添加监听事件
	 * 
	 * @param b
	 * @param keyChar
	 */
	public static void addButtonListioner(JButton b, final char keyChar) {
		sb = new StringBuilder();

		b.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				// TODO Auto-generated method stub
				super.mouseClicked(e);
				sb.append(keyChar);
				resultText.setText(sb.toString());
				Caculator.keyChar = keyChar;

				// 如果输入的是数字，则将输入放入操作数
				if (keyChar >= '0' && keyChar <= '9') {

					// 还未输入运算符，值放入第一个操作数
					if (numInputOrder == 0) {
						sb.delete(0, sb.length());
						sb.append(keyChar);
						resultText.setText(sb.toString());

						lastNum.append(keyChar);

						// 输入过一个运算符，值放入第二个操作数
					} else if (numInputOrder == 1) {
						currentNum.append(keyChar);
					}

					// 如果输入的是操作符，则将输入放入操作符
				} else if (keyChar == '+' || keyChar == '-' || keyChar == '*'
						|| keyChar == '/') {

					operate = keyChar;
					numInputOrder++;

					// 输入过兩个运算符，计算并将结果放入第一个运算符
					if (numInputOrder == 2) {
						double rTemp = calc(oTemp);
						lastNum.delete(0, lastNum.length());
						currentNum.delete(0, currentNum.length());
						lastNum.append(rTemp);
						sb.delete(0, sb.length());
						sb.append(rTemp + "" + keyChar);
						resultText.setText(sb.toString());
					}
					numInputOrder = 1;
					oTemp = keyChar;

					// 如果输入的是小数点，则将输入加到操作数后面
				} else if (keyChar == '.') {
					if (numInputOrder == 0) {
						currentNum.append(keyChar);
					} else if (numInputOrder == 1) {
						lastNum.append(keyChar);
					}

					// 如果输入的是等号，计算结果并显示到TextField
				} else if (keyChar == '=') {
					result = calc(operate);
					System.out.println(lastNum.toString() + operate
							+ currentNum.toString() + "=" + result);
					sb.append(result);
					resultText.setText(sb.toString());

					numInputOrder = 0;
					lastNum.delete(0, lastNum.length());
					currentNum.delete(0, currentNum.length());

				}

			}

		});
	}

	/**
	 * 拿到按键值
	 * 
	 * @return
	 */
	public static char getKeyChar() {
		return keyChar;
	}

	/**
	 * 计算结果
	 * 
	 * @param operate
	 * @return
	 */
	public static double calc(char operate) throws NumberFormatException {

		switch (operate) {
		case '+':
			return Double.parseDouble(lastNum.toString())
					+ Double.parseDouble(currentNum.toString());
		case '-':
			return Double.parseDouble(lastNum.toString())
					- Double.parseDouble(currentNum.toString());
		case '*':
			return Double.parseDouble(lastNum.toString())
					* Double.parseDouble(currentNum.toString());
		case '/':
			return Double.parseDouble(lastNum.toString())
					/ Double.parseDouble(currentNum.toString());
		default:
			return 0;
		}

	}
}
